package com.study.zookeeper.config;

import com.study.common.annotation.MyReference;
import com.study.connect.message.ServiceInvokeDTO;
import com.study.zookeeper.client.IInvokeService;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * @包名称 com.study.zookeeper.config
 * @类描述 <pre></pre>
 * @作者 zhangbo
 * @创建时间 2020/6/7.
 * @版本 1.00
 * @修改记录 <pre>
 *     版本           修改人         修改日期         修改内容描述
 *     -----------------------------------------------------------
 *     1.00           zhangbo        2020/6/7.           类创建
 *     -----------------------------------------------------------
 * </pre>
 */
@Slf4j
public class ClientInvokeHandler<T> implements InvocationHandler {

    private T target;

    private MyReference annotation;

    private IInvokeService invokeService;


    public ClientInvokeHandler(T target, MyReference annotation, IInvokeService invokeService) {
        this.target = target;
        this.annotation = annotation;
        this.invokeService = invokeService;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        log.debug("className:{},methodName:{},args:{}", ((Class) this.target).getName(), method.getName(), args);
        log.debug("version:{},retrys:{}", annotation.version(), annotation.retrys());
        ServiceInvokeDTO serviceInvokeDTO = new ServiceInvokeDTO();

        serviceInvokeDTO.setServiceName(((Class) this.target).getName());
        serviceInvokeDTO.setMethodName(method.getName());
        serviceInvokeDTO.setRetrys(annotation.retrys());
        serviceInvokeDTO.setVersion(annotation.version());
        if (null != args && args.length > 0) {
            List<Object> paramList = new ArrayList<>(args.length);
            List<Class<?>> paramTypeList = new ArrayList<>(args.length);
            for (Object arg : args) {
                paramList.add(arg);
                paramTypeList.add(arg.getClass());
            }
            serviceInvokeDTO.setParams(paramList);
            serviceInvokeDTO.setParamTypes(paramTypeList);

        }

        return invokeService.invoke(serviceInvokeDTO);

    }
}
